import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/*9.19.1 Problem
 You need to create and/or extract from a JAR archive or a file in the PkZip or WinZip format*/
public class UnZip {
	private static final String EXTRACT = null;
	private static final int LIST = 0;

	public static void main(String[] argv) {
		UnZip u = new UnZip();
		for (int i = 0; i < argv.length; i++) {
			if ("-x".equals(argv[i])) {
				u.setMode(EXTRACT);
				continue;
			}
			String candidate = argv[i];
			// System.err.println("Trying path " + candidate);
			if (candidate.endsWith(".zip") || candidate.endsWith(".jar"))
				u.unZip(candidate);
			else
				System.err.println("Not a zip file? " + candidate);
		}
		System.err.println("All done!");
	}

	/** Construct an UnZip object. Just allocate the buffer */
	UnZip() {
		byte[] b = new byte[8092];
	}

	/** Set the Mode (list, extract). */
	/** Set the Mode (list, extract). */
	protected void setMode(String m) {
		String mode;
		//if (m == LIST || m == EXTRACT)
			mode = m;
	}

	/** For a given Zip file, process each entry. */
	public void unZip(String fileName) {
		try {
			ZipFile zippy = new ZipFile(fileName);
			Enumeration<? extends ZipEntry> all = zippy.entries();
			while (all.hasMoreElements()) {
				getFile(((ZipEntry) (all.nextElement())));
			}
		} catch (IOException err) {
			System.err.println("IO Error: " + err);
			return;
		}
	}

	/**
	 * Process one file from the zip, given its name. Either print the name, or
	 * create the file on disk.
	 */
	protected void getFile(ZipEntry e) throws IOException {
		String zipName = e.getName();
		String mode = null;
		if (mode == EXTRACT) {
			// double-check that the file is in the zip
			// if a directory, mkdir it (remember to
			// create intervening subdirectories if needed!)
			if (zipName.endsWith("/")) {
				new File(zipName).mkdirs();
				return;
			}
			// Else must be a file; open the file for output
			System.err.println("Creating " + zipName);
			FileOutputStream os = new FileOutputStream(zipName);
			ZipFile zippy = null;
			InputStream is = zippy.getInputStream(e);
			int n = 0;
			byte[] b = null;
			while ((n = is.read(b)) > 0)
				os.write(b, 0, n);
			is.close();
			os.close();
		} else
		// Not extracting, just list
		if (e.isDirectory()) {
			System.out.println("Directory " + zipName);
		} else {
			System.out.println("File " + zipName);
		}
	}
}
